#include "ProfileMenuState.h"
#include "Game.h"
#include "MainMenuState.h"

#include "ProfileManager.h"
#include "../SGD Wrappers/SGD_String.h"
#include "BitmapFont.h"

ProfileMenuState* ProfileMenuState::pInstance = nullptr;
/*static*/ ProfileMenuState* ProfileMenuState::GetInstance( void )
{
	// Allocate the static pointer if necessary
	if( pInstance == nullptr )
		pInstance = new ProfileMenuState;

	// Return the singleton
	return pInstance;
}
/*static*/ void ProfileMenuState::DeleteInstance( void )
{
	delete pInstance;
	pInstance = nullptr;
}

// Update
void ProfileMenuState::Update(float deltaTime)
{
	if(controllerDelay > 0.0f)
		controllerDelay -= deltaTime;
	if(!isNaming)
	{
#pragma region Profile Menu Input
		if(dI->KeyPressed(DIK_ESCAPE))
		{
			Game::GetInstance()->ChangeState(MainMenuState::GetInstance());
			return;
		}
		if(dI->KeyPressed(DIK_RETURN) || dI->JoystickButtonPressed(0))
		{
			if(cursor < 5)
			{
				if(!isDeleting)
					ProfileManager::GetInstance()->setCurProfile(cursor);
				else
				{
					ProfileManager::GetInstance()->deleteProfile(cursor);
					isDeleting = false;
				}
			}
			else
			{
				switch(cursor)
				{
				case 5:
					Game::GetInstance()->ChangeState(MainMenuState::GetInstance());
					break;
				case 6:
					curName = ProfileManager::GetInstance()->getCurProfile().getName();
					if(curName != "DEMO PROFILE")
					{
						isNaming = true;
						if(curName == "INSERT NAME HERE")
						{
							curName = "A";
						}
						curLetter = curName[curSelectedLetter];
						isDeleting = false;
					}
					break;
				case 7:
					//isDeleting = true;
					if(ProfileManager::GetInstance()->getCurProfileNum() != 4)
						ProfileManager::GetInstance()->deleteProfile(ProfileManager::GetInstance()->getCurProfileNum());
					break;
				}
				return;
			}
			if(isDeleting)
				isDeleting = false;
		}
		if(dI->KeyPressed(DIK_UP) || dI->KeyPressed(DIK_W) || dI->JoystickDPadPressed(DIR_UP) || (CSGD_DirectInput::GetInstance()->JoystickGetLStickYNormalized() < 0 && controllerDelay <= 0.0f))
		{
			controllerDelay = 0.17f;
			if(cursor > 0)
			{
				if( cursor != 6)
					--cursor;
				else
					cursor = 4;
			}
			else
				cursor = 6;
		}
		else if (dI->KeyPressed(DIK_DOWN) || dI->KeyPressed(DIK_S) || dI->JoystickDPadPressed(DIR_DOWN) || (CSGD_DirectInput::GetInstance()->JoystickGetLStickYNormalized() > 0 && controllerDelay <= 0.0f))
		{
			controllerDelay = 0.25f;
			if(cursor < 4)
				++cursor;
			else if (cursor == 6)
				cursor = 0;
			else
				cursor = 6;
		}
		if(dI->KeyPressed(DIK_LEFT) || dI->KeyPressed(DIK_A) || dI->JoystickDPadDown(DIR_LEFT) || (CSGD_DirectInput::GetInstance()->JoystickGetLStickXNormalized() < 0 && controllerDelay <= 0))
		{
			controllerDelay = 0.25f;
			if(cursor >= 4)
			{
				if(cursor >= 6)
					--cursor;
				else
					cursor = 7;
			}
			else
			{
				cursor = 5;
			}
		}
		if(dI->KeyPressed(DIK_RIGHT) || dI->KeyPressed(DIK_D) || dI->JoystickDPadDown(DIR_RIGHT) || (CSGD_DirectInput::GetInstance()->JoystickGetLStickXNormalized() > 0 && controllerDelay <= 0))
		{
			controllerDelay = 0.25f;
			if(cursor >= 4)
			{
				if(cursor <= 6 )
				{
					++cursor;
				}
				else
				{
					cursor = 5;
				}
			}
			else
			{
				cursor = 7;
			}
		}
#pragma endregion Profile Input
	}
	//Naming input
	else
	{
		if(dI->KeyPressed(DIK_ESCAPE))
		{
			isNaming = false;
			return;
		}
		if(dI->KeyPressed(DIK_BACKSPACE) || dI->KeyPressed(DIK_DELETE))
		{
			curName.pop_back();
			curSelectedLetter -= 1;
			if(curSelectedLetter < 0)
			{
				curSelectedLetter = 0;
			}
		}
		if(dI->KeyPressed(DIK_RETURN) || dI->JoystickButtonPressed(0))
		{
			ProfileManager::GetInstance()->getCurProfile().setName(curName);
			curName = "A";
			curLetter = 'A';
			curSelectedLetter = 0;
			isNaming = false;
			return;
		}
		if(dI->KeyPressed(DIK_UP) || dI->KeyPressed(DIK_W) || dI->JoystickDPadPressed(DIR_UP) || (CSGD_DirectInput::GetInstance()->JoystickGetLStickYNormalized() < 0 && controllerDelay <= 0.0f))
		{
			controllerDelay = 0.17f;
			//if(namingIsSelected)
			{
				curLetter -= 1;
				if(curLetter < 'A')
				{
					curLetter = 'Z';
				}
				if((unsigned int)curSelectedLetter < curName.length())
					curName[curSelectedLetter] = curLetter;
				else
				{
					curName += curLetter;
				}
			}
		}
		else if (dI->KeyPressed(DIK_DOWN) || dI->KeyPressed(DIK_S) || dI->JoystickDPadPressed(DIR_DOWN) || (CSGD_DirectInput::GetInstance()->JoystickGetLStickYNormalized() > 0 && controllerDelay <= 0.0f))
		{
			controllerDelay = 0.25f;
			//if(namingIsSelected)
			{
				curLetter += 1;
				if(curLetter > 'Z')
				{
					curLetter = 'A';
				}
				if((unsigned int)curSelectedLetter < curName.length())
					curName[curSelectedLetter] = curLetter;
				else
				{
					curName += curLetter;
				}
			}
		}
		if(dI->KeyPressed(DIK_LEFT) || dI->KeyPressed(DIK_A))
		{
			//if(!namingIsSelected)
			{
				curSelectedLetter -=1;
				if(curSelectedLetter < 0)
				{
					curSelectedLetter = curName.length();
					if(curSelectedLetter > 12)
					{
						curSelectedLetter = 12;
					}
				}
				else
					curLetter = curName[curSelectedLetter];
			}
		}
		if(dI->KeyPressed(DIK_RIGHT) || dI->KeyPressed(DIK_D))
		{
			//if(!namingIsSelected)
			{
				curSelectedLetter +=1;
				if(curSelectedLetter > 12)
				{
					curSelectedLetter = 12;
				}
				if((unsigned int)curSelectedLetter > curName.length())
				{
					curSelectedLetter = 0;
				}
				if(curSelectedLetter != curName.length())
				{
					curLetter = curName[curSelectedLetter];
				}
			}
		}
	}
}

// Render
void ProfileMenuState::Render(void) const
{
	RECT renderRect;

	for(int i =0; i < 5; ++i)
	{
		renderRect.top	 = 100 + 60*i + 20*i;
		renderRect.bottom = 160 + 60*i + 20*i;
		renderRect.left	 = 250; renderRect.right = 550;


		D3D->DrawRect(renderRect,D3DCOLOR_ARGB(255,255,0,0));
		if(i == ProfileManager::GetInstance()->getCurProfileNum())
		{
			RECT tempRect = renderRect;
			tempRect.bottom -= 2;
			tempRect.top += 2;
			tempRect.left += 2;
			tempRect.right -= 2;
			D3D->DrawHollowRect(tempRect,D3DCOLOR_ARGB(255,0,255,255));
		}
		ostringstream profileName;
		switch(i)
		{
		case 0:
			if(ProfileManager::GetInstance()->getProfile(0) == nullptr)
			{
				BitmapFont::GetInstance()->Print("Profile 1", (float)renderRect.left, (float)renderRect.top ,0, D3DCOLOR_ARGB(255,0,0,0));
			}
			else
			{
				profileName << ProfileManager::GetInstance()->getProfile(0)->getName().c_str();
				BitmapFont::GetInstance()->Print(profileName.str().c_str(), (float)renderRect.left, (float)renderRect.top ,0, D3DCOLOR_ARGB(255,0,0,0));
				profileName.str((""));
				profileName <<  "Levels Unlocked:  " << ProfileManager::GetInstance()->getProfile(0)->getLevelsUnlocked();
				BitmapFont::GetInstance()->Print(profileName.str().c_str(), (float)renderRect.left+5, (float)renderRect.top+30 ,0, D3DCOLOR_ARGB(255,0,0,0));
				profileName.str((""));
			}
			break;
		case 1:
			if(ProfileManager::GetInstance()->getProfile(1) == nullptr)
			{
				BitmapFont::GetInstance()->Print("Profile 2", (float)renderRect.left, (float)renderRect.top ,0, D3DCOLOR_ARGB(255,0,0,0));
			}
			else
			{
				profileName << ProfileManager::GetInstance()->getProfile(1)->getName().c_str();
				BitmapFont::GetInstance()->Print(profileName.str().c_str(), (float)renderRect.left, (float)renderRect.top ,0, D3DCOLOR_ARGB(255,0,0,0));
				profileName.str((""));
				profileName <<  "Levels Unlocked:  " << ProfileManager::GetInstance()->getProfile(1)->getLevelsUnlocked();
				BitmapFont::GetInstance()->Print(profileName.str().c_str(), (float)renderRect.left+5, (float)renderRect.top+30 ,0, D3DCOLOR_ARGB(255,0,0,0));
				profileName.str((""));
			}
			break;
		case 2:
			if(ProfileManager::GetInstance()->getProfile(2) == nullptr)
			{
				BitmapFont::GetInstance()->Print("Profile 3", (float)renderRect.left, (float)renderRect.top ,0, D3DCOLOR_ARGB(255,0,0,0));
			}
			else
			{
				profileName << ProfileManager::GetInstance()->getProfile(2)->getName().c_str();
				BitmapFont::GetInstance()->Print(profileName.str().c_str(), (float)renderRect.left, (float)renderRect.top ,0, D3DCOLOR_ARGB(255,0,0,0));
				profileName.str((""));
				profileName <<  "Levels Unlocked:  " << ProfileManager::GetInstance()->getProfile(2)->getLevelsUnlocked();
				BitmapFont::GetInstance()->Print(profileName.str().c_str(), (float)renderRect.left+5, (float)renderRect.top+30 ,0, D3DCOLOR_ARGB(255,0,0,0));
				profileName.str((""));
			}
			break;
		case 3:
			if(ProfileManager::GetInstance()->getProfile(3) == nullptr)
			{
				BitmapFont::GetInstance()->Print("Profile 4", (float)renderRect.left, (float)renderRect.top ,0, D3DCOLOR_ARGB(255,0,0,0));
			}
			else
			{
				profileName << ProfileManager::GetInstance()->getProfile(3)->getName().c_str();
				BitmapFont::GetInstance()->Print(profileName.str().c_str(), (float)renderRect.left, (float)renderRect.top ,0, D3DCOLOR_ARGB(255,0,0,0));
				profileName.str((""));
				profileName <<  "Levels Unlocked:  " << ProfileManager::GetInstance()->getProfile(3)->getLevelsUnlocked();
				BitmapFont::GetInstance()->Print(profileName.str().c_str(), (float)renderRect.left+5, (float)renderRect.top+30 ,0, D3DCOLOR_ARGB(255,0,0,0));
				profileName.str((""));
			}
			break;
		case 4:
			if(ProfileManager::GetInstance()->getProfile(4) == nullptr)
			{
				BitmapFont::GetInstance()->Print("Profile 5", (float)renderRect.left, (float)renderRect.top ,0, D3DCOLOR_ARGB(255,0,0,0));
			}
			else
			{
				profileName << ProfileManager::GetInstance()->getProfile(4)->getName().c_str();
				BitmapFont::GetInstance()->Print(profileName.str().c_str(), (float)renderRect.left, (float)renderRect.top ,0, D3DCOLOR_ARGB(255,0,0,0));
				profileName.str((""));
				profileName <<  "Levels Unlocked:  " << ProfileManager::GetInstance()->getProfile(4)->getLevelsUnlocked();
				BitmapFont::GetInstance()->Print(profileName.str().c_str(), (float)renderRect.left+5, (float)renderRect.top+30 ,0, D3DCOLOR_ARGB(255,0,0,0));
				profileName.str((""));
			}
			break;
		}
	}
	renderRect.top = Game::GetInstance()->GetScreenHeight()-100;
	renderRect.bottom = Game::GetInstance()->GetScreenHeight()-20;
	renderRect.left = 5; renderRect.right = 200;
	D3D->DrawRect(renderRect,D3DCOLOR_ARGB(255,255,0,0));
	BitmapFont::GetInstance()->Print("Back", (float)renderRect.left, (float)renderRect.top ,0, D3DCOLOR_ARGB(255,0,0,0));

	renderRect.top = Game::GetInstance()->GetScreenHeight()-100;
	renderRect.bottom = Game::GetInstance()->GetScreenHeight()-20;
	renderRect.left = 300; renderRect.right = 500;
	D3D->DrawRect(renderRect,D3DCOLOR_ARGB(255,255,0,0));
	BitmapFont::GetInstance()->Print("Change Name", (float)renderRect.left, (float)renderRect.top ,0, D3DCOLOR_ARGB(255,0,0,0));

	renderRect.top = Game::GetInstance()->GetScreenHeight()-100;
	renderRect.bottom = Game::GetInstance()->GetScreenHeight()-20;
	renderRect.left = Game::GetInstance()->GetScreenWidth() - 200; renderRect.right = Game::GetInstance()->GetScreenWidth()-5;
	D3D->DrawRect(renderRect,D3DCOLOR_ARGB(255,255,0,0));
	BitmapFont::GetInstance()->Print("Delete", (float)renderRect.left, (float)renderRect.top ,0, D3DCOLOR_ARGB(255,0,0,0));


	RECT selectedRect;
	if(cursor < 5)
	{
		selectedRect.top = 100 + 60*cursor + 20*cursor;
		selectedRect.bottom = 160 + 60*cursor + 20*cursor;
		selectedRect.left = 250; selectedRect.right = 550;
	}
	else if(cursor == 5)
	{
		selectedRect.top = Game::GetInstance()->GetScreenHeight()-100;
		selectedRect.bottom = Game::GetInstance()->GetScreenHeight()-20;
		selectedRect.left = 5; selectedRect.right = 200;
	}
	else if(cursor == 6)
	{
		selectedRect.top = Game::GetInstance()->GetScreenHeight()-100;
		selectedRect.bottom = Game::GetInstance()->GetScreenHeight()-20;
		selectedRect.left = 300; selectedRect.right = 500;
	}
	else if(cursor == 7)
	{
		selectedRect.top = Game::GetInstance()->GetScreenHeight()-100;
		selectedRect.bottom = Game::GetInstance()->GetScreenHeight()-20;
		selectedRect.left = Game::GetInstance()->GetScreenWidth() - 200; selectedRect.right = Game::GetInstance()->GetScreenWidth()-5;
	}
	D3D->DrawHollowRect(selectedRect,D3DCOLOR_ARGB(255,255,255,0),3);

	//Naming rendering:
	if(isNaming)
	{
		//semitransparent black rect
		RECT screenRect = {0,0,Game::GetInstance()->GetScreenWidth(),Game::GetInstance()->GetScreenHeight()};
		D3D->DrawRect(screenRect,D3DCOLOR_ARGB(75,0,0,0));
		RECT nameRect = {Game::GetInstance()->GetScreenWidth()/2 - 175, Game::GetInstance()->GetScreenHeight()/2 - 150,
			Game::GetInstance()->GetScreenWidth()/2 + 175, Game::GetInstance()->GetScreenHeight()/2 + 150};
		D3D->DrawRect(nameRect,D3DCOLOR_ARGB(254,50,50,50));
		BitmapFont::GetInstance()->Print("Enter your name:", Game::GetInstance()->GetScreenWidth()/2 - 100.0f, Game::GetInstance()->GetScreenHeight()/2 - 150.0f,
										0, D3DCOLOR_ARGB(240,230,230,0));
		BitmapFont::GetInstance()->Print(curName, Game::GetInstance()->GetScreenWidth()*0.5f - 100, Game::GetInstance()->GetScreenHeight()*0.5f,
								0, D3DCOLOR_ARGB(240,200,230,0));
		BitmapFont::GetInstance()->Print(curName, Game::GetInstance()->GetScreenWidth()*0.5f - 100, Game::GetInstance()->GetScreenHeight()*0.5f,
								0, D3DCOLOR_ARGB(240,200,230,0));

		//TODO: update this to use letter spacing
		RECT underscore = {Game::GetInstance()->GetScreenWidth()/2 - 100 + 20*curSelectedLetter, Game::GetInstance()->GetScreenHeight()/2+25,
						Game::GetInstance()->GetScreenWidth()/2 - 80 + 20*curSelectedLetter, Game::GetInstance()->GetScreenHeight()/2+30};
		D3D->DrawRect(underscore,D3DCOLOR_ARGB(240,200,230,0));

		BitmapFont::GetInstance()->Print("Backspace to remove a letter.", Game::GetInstance()->GetScreenWidth()/2 - 200.0f, Game::GetInstance()->GetScreenHeight()/2 +90.0f,
								0, D3DCOLOR_ARGB(240,230,230,0));
		BitmapFont::GetInstance()->Print("Press Enter to confirm, Escape to exit.", Game::GetInstance()->GetScreenWidth()/2 - 250.0f, Game::GetInstance()->GetScreenHeight()/2 +150.0f,
								0, D3DCOLOR_ARGB(240,230,230,0));
	}
}

// Enter
//	- Used to initialize the game state.
void ProfileMenuState::Enter(void)
{
	GameState::Enter();
}

// Exit
//	- Used to clean up the game state.
void ProfileMenuState::Exit(void)
{
	GameState::Exit();
	DeleteInstance();
}


ProfileMenuState::ProfileMenuState(void)
{
	cursor = 0;
	isDeleting = false;
	isNaming = false;
	//namingIsSelected = true;
	curSelectedLetter = 0;
	curLetter = 'A';
	curName	= "A";
}
ProfileMenuState::~ProfileMenuState(void)
{

}